<script setup>
import { ref } from 'vue';

const props = defineProps({
  modelValue: { type: Array, required: true },
  keyPropName: { type: String }
})
const emit = defineEmits(['update:modelValue'])

const dragIndex = ref(-1)

let sourceInfo = { index: -1, dom: null }

const dragstart = (e, index) => {
  setTimeout(() => {
    dragIndex.value = index
  }, 0);
  sourceInfo.dom = e.target // 拖拽的当前元素
  sourceInfo.index = index
  e.dataTransfer.effectAllowed = 'move'
}

const drop = (e, index) => {
  if (!sourceInfo.dom || sourceInfo.dom === e.target) return // 当前dom不存在或者进入的元素为自身时
  let renderArr = [ ...props.modelValue ]
  const temp = renderArr[index]
  renderArr[index] = renderArr[sourceInfo.index]
  renderArr[sourceInfo.index] = temp
  dragIndex.value = -1
  sourceInfo = { index: -1, dom: null }
  emit('update:modelValue', [ ...renderArr ])
}

</script>

<template>
  <div class="drag-container">
    <TransitionGroup name="slide" tag="div">
      <div 
        class="drag-item" 
        draggable="true" 
        @dragstart="(e) => dragstart(e, key)"
        @dragover.prevent
        @drop="(e) => drop(e, key)"
        v-for="(item, key) in props.modelValue"
        :key="props.keyPropName ? item[props.keyPropName] : item.id"
      >
        <slot name="scope" v-bind="item"></slot>
      </div>
    
    </TransitionGroup>
    
  </div>

</template>

<style scoped lang="less">
/* 定义过渡动画 */
.slide-move,
.slide-enter-active,
.slide-leave-active {
  transition: all 0.5s ease;
}

.slide-enter-from,
.slide-leave-to {
  opacity: 0;
  transform: translateX(30px);
}

.slide-leave-active {
  position: absolute;
}

.drag-container {
  .drag-item {
    &:not(:last-child) {
      margin-bottom: 12px;
    }
  }
}



</style>